package com.yh.csx.crm.service;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.yh.csx.crm.core.enums.*;
import com.yh.csx.crm.core.exception.BusinessException;
import com.yh.csx.crm.core.util.BeanUtils;
import com.yh.csx.crm.core.util.DateUtils;
import com.yh.csx.crm.core.util.OrderNumberGenerator;
import com.yh.csx.crm.dao.*;
import com.yh.csx.crm.po.*;
import com.yh.csx.crm.qo.ApprovalListQo;
import com.yh.csx.crm.qo.ReportCreditWarningQo;
import com.yh.csx.crm.service.logic.SapLogic;
import com.yh.csx.crm.service.request.ReprotAccountAgeReq;
import com.yh.csx.crm.service.request.TodoListReq;
import com.yh.csx.crm.service.request.UploadFile;
import com.yh.csx.crm.service.request.UploadFilePO;
import com.yh.csx.crm.service.response.AppApprovalFlowLogResp;
import com.yh.csx.crm.service.response.AppGetExpandInfoResp;
import com.yh.csx.crm.service.response.ApprovalFlowLogResp;
import com.yh.csx.crm.service.response.CustomerAddBigResp;
import com.yh.csx.crm.service.response.CustomerSnapshotResp;
import com.yh.csx.crm.service.response.IndexResp;
import com.yh.csx.crm.service.response.SnapshotCompareResp;
import com.yh.csx.crm.service.vo.ApprovalStatus;
import com.yh.csx.crm.service.vo.FlowNodeJSON;
import com.yh.csx.crm.service.vo.PageWrap;
import com.yh.csx.crm.service.vo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * AuditService class
 *
 * @author huyalin
 * @date 2019/2/20
 */
@Slf4j
@Service
public class ApprovalService {

    @Autowired
    ApprovalMapper approvalMapper;
    @Autowired
    ApprovalTodoMapper approvalTodoMapper;
    @Autowired
    ApprovalCompletedMapper approvalCompletedMapper;
    @Autowired
    SysFlowConfigMapper sysFlowConfigMapper;
    @Autowired
    SysNodeConfigMapper sysNodeConfigMapper;
    @Autowired
    CustomerMapper customerMapper;
    @Autowired
    CustomerSnapshotMapper customerSnapshotMapper;
    @Autowired
    SapLogic sapLogic;
    @Autowired
    CustomerCompanyExtMapper customerCompanyExtMapper;
    @Autowired
    SysCompanyCodeMapper sysCompanyCodeMapper;
    @Autowired
    SysSalesPermissionMapper sysSalesPermissionMapper;
    @Autowired
    CustomerService customerService;
    @Autowired
    GeoService geoService;
    @Autowired
    ReportFormsService reportFormsService;
    @Autowired
    SaleService saleService;
    @Autowired
    MessageService messageService;

    @Value("${message.enable:false}")
    private boolean isMessageEnable;


    /**
     * App端首页获取待办任务统计列表
     *
     * @param user
     * @return
     */
    public IndexResp getIndexTodoList(User user) {
        ApprovalListQo approvalListQo = new ApprovalListQo();

        List<String> approvalTypes = new ArrayList();
        approvalTypes.add(ApprovalTypeEnum.NEW.getCode());

        approvalListQo.setUserId(user.getUserId());
        approvalListQo.setApprovalTypeCodes(approvalTypes);
        
        List<ApprovalAndCustomerSnapshot> newTodo = approvalTodoMapper.selectByExample(approvalListQo);

        approvalTypes.clear();
        approvalTypes.add(ApprovalTypeEnum.CREDIT.getCode());
        approvalTypes.add(ApprovalTypeEnum.TEMP_CREDIT.getCode());
        approvalListQo.setApprovalTypeCodes(approvalTypes);

        List<ApprovalAndCustomerSnapshot> creditTodo = approvalTodoMapper.selectByExample(approvalListQo);

        approvalTypes.clear();
        approvalTypes.add(ApprovalTypeEnum.MODIFY.getCode());
        approvalListQo.setApprovalTypeCodes(approvalTypes);

        List<ApprovalAndCustomerSnapshot> modifyTodo = approvalTodoMapper.selectByExample(approvalListQo);

        /*信控预警*/
        ReportCreditWarningQo qo = new ReportCreditWarningQo();
        PageWrap creditWarningList = reportFormsService.getCreditWarningList(user, qo);

        /*应收账款*/
        ReprotAccountAgeReq req = new ReprotAccountAgeReq();
        PageWrap accountAgeList = reportFormsService.getAccountAgeList(user, req);

        IndexResp indexResp = new IndexResp();
        indexResp.setNewCustomerApproval(newTodo.size());
        indexResp.setCreditApproval(creditTodo.size());
        indexResp.setModifyApproval(modifyTodo.size());
        indexResp.setReceivable(accountAgeList.getTotalNum());
        indexResp.setCreditAlert(creditWarningList.getTotalNum());
        SysSalesPermission sales = saleService.findSalesPermission(user.getUserId());
        if (sales != null) {
            // TODO 若手机号码、姓名、工号和用户中心不一致时，进行修正
            indexResp.setUserId(user.getUserId());
            indexResp.setUserName(user.getUserName());
            indexResp.setPosition(sales.getPosition());
            indexResp.setPhone(sales.getPhone());
            indexResp.setWorkNumber(sales.getWorkNumber());

        }
        return indexResp;
    }

    /**
     * APP端审批流展示
     * @param approvalId
     * @return
     */
    public AppApprovalFlowLogResp getAppApprovalFlow(Long approvalId) {
        Approval approval = approvalMapper.selectByPrimaryKey(approvalId);
        AppApprovalFlowLogResp appApprovalFlowLogResp = new AppApprovalFlowLogResp();
        List<ApprovalFlowLogResp> approvalFlowNode = this.getApprovalFlowNode(approval);
        List<AppApprovalFlowLogResp.FlowNode> flowNodeList = BeanUtils.convertList(AppApprovalFlowLogResp.FlowNode.class, approvalFlowNode);
        for (int i = 0; i < flowNodeList.size() - 1; i++) {
            if (flowNodeList.get(i).getNodeCode().equals(approval.getCurrentNodeCode())) {
                appApprovalFlowLogResp.setCurrentNode(flowNodeList.get(i));
                appApprovalFlowLogResp.setNextNode(flowNodeList.get(i + 1));
            }
        }
        appApprovalFlowLogResp.setFlowNodeList(flowNodeList);

        return appApprovalFlowLogResp;
    }

    /**
     * 审批流展示
     * @param approval
     * @return
     */
    private List<ApprovalFlowLogResp> getApprovalFlowNode(Approval approval) {
        List<ApprovalFlowLogResp> respList = new ArrayList<>();
        if (approval == null) {
            return respList;
        }
        for (FlowNodeJSON flowNode : JSON.parseArray(approval.getFlowNode(), FlowNodeJSON.class)) {
            ApprovalCompleted approvalCompleted = approvalCompletedMapper.selectByApprovalIdAndNode(approval.getId(), flowNode.getNode().getCode());
            ApprovalFlowLogResp approvalFlowLogResp = new ApprovalFlowLogResp();
            approvalFlowLogResp.setStep(flowNode.getNode().getName() + "审批");
            approvalFlowLogResp.setNodeCode(flowNode.getNode().getCode());

            if (flowNode.getNode().getCode().equals(ApprovalFlowEnum.BEGIN.getCode())) {
                approvalFlowLogResp.setOperationAction(ApprovalFlowEnum.BEGIN.getName());
                approvalFlowLogResp.setOperationTime(approval.getCreateTime());
                approvalFlowLogResp.setOperationPerson(flowNode.getPerson().get(0).getName());
            } else if (approvalCompleted != null) {
                approvalFlowLogResp.setOperationAction(approvalCompleted.getConfirm() ? "通过" : "拒绝");
                approvalFlowLogResp.setOperationTime(approvalCompleted.getCreateTime());
                approvalFlowLogResp.setOperationPerson(approvalCompleted.getApprovalUserName());
                approvalFlowLogResp.setRemark(approvalCompleted.getRejectReason());
            } else {
                StringBuilder stringBuilder = new StringBuilder();
                List<FlowNodeJSON.Person> personList = flowNode.getPerson();
                for (int i = 0; i < personList.size(); i++) {
                    stringBuilder.append(personList.get(i).getName());
                    if (i < personList.size() - 1) {
                        stringBuilder.append("，");
                    }
                }
                approvalFlowLogResp.setOperationPerson(stringBuilder.toString());
            }
            respList.add(approvalFlowLogResp);
        }
        return respList;
    }

    /**
     * 获取审批流记录 01审批单 02客户
     *
     * @param
     * @return
     */
    public List<ApprovalFlowLogResp> getApprovalFlow(Long id, String type) {
        if (Objects.isNull(id) || StringUtils.isBlank(type)) {
            throw new BusinessException("id和类型不能为空");
        }
        Approval approval = null;
        if (type.equals("02")) {
            List<Approval> approvalList = approvalMapper.selectByCustomerId(id);
            for (Approval app : approvalList) {
                if (app.getApprovalType().equals(ApprovalTypeEnum.NEW.getCode())) {
                    approval = app;
                }
            }
        } else {
            approval = approvalMapper.selectByPrimaryKey(id);
        }
        if (Objects.isNull(approval)) {
            return null;
        }
        List<ApprovalFlowLogResp> approvalFlowNode = this.getApprovalFlowNode(approval);
        return approvalFlowNode;
    }


    /**
     * 判断是否有处理中的申请
     *
     * @param customerId
     * @return
     */
    public boolean isNotRepeatStart(Long customerId) {
        List<Approval> approvalList = approvalMapper.selectByCustomerIdAndStatus(customerId, ApprovalStatusEnum.PENDING.getCode());
        if (approvalList != null && approvalList.size() > 0) {
            return false;
        }
        return true;
    }

    /**
     * 查找客户审批中的记录
     *
     * @param customerId
     * @return
     */
    public Approval findPendingApproval(Long customerId) {
        List<Approval> approvals = approvalMapper.selectByCustomerIdAndType(customerId, ApprovalTypeEnum.NEW.getCode());
        return CollectionUtils.isNotEmpty(approvals) ? approvals.get(0) : null;
    }


    /**
     * 发起审批
     *
     * @param user             发起用户
     * @param approvalTypeEnum 审批类型
     * @param
     * @param startReason      发起原因
     */
    @Transactional(rollbackFor = Exception.class)
    public void startApproval(User user, ApprovalTypeEnum approvalTypeEnum, Customer beforeCustomer, Customer afterCustomer, String startReason) {
        if (!this.isNotRepeatStart(beforeCustomer.getId())) {
            throw new BusinessException("已有审批中的单据");
        }
        CustomerSnapshot beforeCustomerSnapshot = BeanUtils.convert(CustomerSnapshot.class, beforeCustomer);
        CustomerSnapshot afterCustomerSnapshot = BeanUtils.convert(CustomerSnapshot.class, afterCustomer);
        /*确定审批流*/
        ApprovalRuleEnum approvalRuleEnum = null;
        if (approvalTypeEnum.getCode().equals(ApprovalTypeEnum.NEW.getCode()) || approvalTypeEnum.getCode().equals(ApprovalTypeEnum.CREDIT.getCode())) {
//            if (afterCustomer.getCooperationMode().equals(CooperationModeEnum.LONG_TERM.getCode())
//                    && afterCustomer.getCreditLimit().compareTo(BigDecimal.ZERO) > 0) {
                if (afterCustomerSnapshot.getCreditLimit().compareTo(ApprovalRuleEnum.LESS_THAN_OR_EQUAL.getBase()) <= 0) {
                    approvalRuleEnum = ApprovalRuleEnum.LESS_THAN_OR_EQUAL;
                }
                if (afterCustomerSnapshot.getCreditLimit().compareTo(ApprovalRuleEnum.LESS_THAN_OR_EQUAL.getBase()) > 0) {
                    approvalRuleEnum = ApprovalRuleEnum.GREATER_THAN;
                }
//            } else {
//                approvalRuleEnum = ApprovalRuleEnum.NOT_APPLICABLE;
//            }
        } else {
            approvalRuleEnum = ApprovalRuleEnum.NOT_APPLICABLE;
        }

        SysFlowConfig sysFlowConfig = sysFlowConfigMapper.selectByApprovalTypeAndRule(approvalTypeEnum.getCode(), approvalRuleEnum.getCode());
        if (Objects.isNull(sysFlowConfig)) {
            throw new BusinessException("没有对应的审批流");
        }
        /*落地客户信息快照*/
        beforeCustomerSnapshot.setId(null);
        afterCustomerSnapshot.setId(null);
        beforeCustomerSnapshot.setCreateTime(null);
        afterCustomerSnapshot.setCreateTime(null);
        beforeCustomerSnapshot.setUpdateTime(null);
        afterCustomerSnapshot.setUpdateTime(null);
        beforeCustomerSnapshot.setCreateBy(user.getUserName());
        afterCustomerSnapshot.setCreateBy(user.getUserName());
        customerSnapshotMapper.insertSelective(beforeCustomerSnapshot);
        customerSnapshotMapper.insertSelective(afterCustomerSnapshot);

        /*落地发起审批记录*/
        List<FlowNodeJSON> flowNodeJSONList = JSON.parseArray(sysFlowConfig.getFlowNode(), FlowNodeJSON.class);
        flowNodeJSONList.forEach(flowNodeJSON -> {
            SysNodeConfig sysNodeConfig = sysNodeConfigMapper.selectByNodeAndProvince(flowNodeJSON.getNode().getCode(), afterCustomerSnapshot.getSalesProvince());
            if (Objects.isNull(sysNodeConfig)) {
                throw new BusinessException("没有对应的审批节点");
            }
            String nodePerson = sysNodeConfig.getNodePerson();
            FlowNodeJSON nodeJSON = JSON.parseObject(nodePerson, FlowNodeJSON.class);
            flowNodeJSON.setPerson(nodeJSON.getPerson());
        });
        List<FlowNodeJSON.Person> startPerson = new ArrayList<>();
        startPerson.add(new FlowNodeJSON.Person(user.getUserId().toString(), user.getUserName()));
        flowNodeJSONList.get(0).setPerson(startPerson);
        String flowNode = JSON.toJSONString(flowNodeJSONList);

        FlowNodeJSON currentNode = flowNodeJSONList.get(1);

        Approval approval = new Approval();
        approval.setCustomerId(afterCustomer.getId());
        approval.setApprovalNumber(OrderNumberGenerator.next());
        approval.setApprovalType(approvalTypeEnum.getCode());
        approval.setCurrentNodeCode(currentNode.getNode().getCode());
        approval.setBeforeSnapshotId(beforeCustomerSnapshot.getId());
        approval.setAfterSnapshotId(afterCustomerSnapshot.getId());
        approval.setFlowNode(flowNode);
        approval.setStartReason(StringUtils.isBlank(startReason) ? approvalTypeEnum.getName() : startReason);
        approval.setStartUserId(user.getUserId());
        approval.setStartUserName(user.getUserName());
        approval.setStatus(ApprovalStatusEnum.PENDING.getCode());
        approval.setCreateBy(user.getUserName());
        approvalMapper.insertSelective(approval);


        /*生成待办*/
        List<FlowNodeJSON.Person> personList = currentNode.getPerson();
        personList.forEach(person -> {
            ApprovalTodo approvalTodo = new ApprovalTodo();
            approvalTodo.setApprovalId(approval.getId());
            approvalTodo.setApprovalUserId(Long.valueOf(person.getCode()));
            approvalTodoMapper.insertSelective(approvalTodo);

            this.sendTodoMessage(approvalTodo.getApprovalUserId(), approval.getApprovalNumber().toString(), approvalTypeEnum.getName());

        });

    }

    /**
     * 发送待处理短信提醒
     * @param salesUserId
     * @param approvalNumber
     * @param approvalType
     */
    private void sendTodoMessage(Long salesUserId, String approvalNumber, String approvalType) {
        if (this.isMessageEnable) {
            SysSalesPermission userSales = sysSalesPermissionMapper.findByUserId(salesUserId);
            if (userSales != null && StringUtils.isNotBlank(userSales.getPhone())) {
                messageService.sendMessage(MessageEnum.TODO_PERSON.getCode(), Arrays.asList(userSales.getPhone()),
                        DateUtils.formatDateTime(new Date()), approvalNumber, approvalType);

            }
        }
    }

    /**
     * 发送审批完结短信提醒
     * @param salesUserId
     * @param approvalNumber
     * @param approvalType
     * @param result
     */
    private void sendCompletedMessage(Long salesUserId, String approvalNumber, String approvalType, String result) {
        if (this.isMessageEnable) {
            SysSalesPermission userSales = sysSalesPermissionMapper.findByUserId(salesUserId);
            if (userSales != null && StringUtils.isNotBlank(userSales.getPhone())) {
                messageService.sendMessage(MessageEnum.START_PERSON.getCode(), Arrays.asList(userSales.getPhone()), DateUtils.formatDateTime(new Date()),
                        approvalNumber, approvalType, result);

            }
        }
    }

    /**
     * 获取待我审批列表
     *
     * @param
     * @return
     */
    public PageWrap<ApprovalAndCustomerSnapshot> getTodoList(User user, TodoListReq req, List<String> approvalTypeCodes) {
        ApprovalListQo qo = BeanUtils.convert(ApprovalListQo.class, req);
        qo.setUserId(user.getUserId());
        qo.setApprovalTypeCodes(approvalTypeCodes);
        if (Objects.nonNull(req.getBeginDate()) && Objects.nonNull(req.getEndDate())) {
            qo.setBeginDateStr(DateUtils.formatDate(req.getBeginDate()));
            qo.setEndDateStr(DateUtils.formatDate(req.getEndDate()));
        }
        Page<Object> page = PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        List<ApprovalAndCustomerSnapshot> approvalAndCustomerSnapshotList = approvalTodoMapper.selectByExample(qo);

        approvalAndCustomerSnapshotList.forEach(approvalAndCustomerSnapshot -> {
            approvalAndCustomerSnapshot.setNewCreditLimit(approvalAndCustomerSnapshot.getCreditLimit());
            approvalAndCustomerSnapshot.setCreditLimit(customerMapper.selectByPrimaryKey(approvalAndCustomerSnapshot.getCustomerId()).getCreditLimit());
            approvalAndCustomerSnapshot.setAddressDetails(approvalAndCustomerSnapshot.getRegionProvinceName()
                    + approvalAndCustomerSnapshot.getRegionCity()
                    + approvalAndCustomerSnapshot.getRegionArea()
                    + approvalAndCustomerSnapshot.getAddressDetails());
            approvalAndCustomerSnapshot.setChangeContent(ApprovalTypeEnum.getName(approvalAndCustomerSnapshot.getApprovalType()));
        });
        PageWrap pageWrap = new PageWrap<>();
        pageWrap.setValue(page);
        pageWrap.setResult(approvalAndCustomerSnapshotList);
        return pageWrap;
    }

    /**
     * 获取我已完成审批列表
     *
     * @param req
     * @return
     */
    public PageWrap getCompletedList(User user, TodoListReq req, List<String> approvalTypeCodes) {
        ApprovalListQo qo = BeanUtils.convert(ApprovalListQo.class, req);
        qo.setUserId(user.getUserId());
        qo.setApprovalTypeCodes(approvalTypeCodes);
//        if (StringUtils.isNotBlank(req.getStatus())) {
//            if (req.getStatus().equals(ApprovalStatusEnum.PASS.getCode())) {
//                qo.setConfirm(true);
//            }
//            if (req.getStatus().equals(ApprovalStatusEnum.REJECT.getCode())) {
//                qo.setConfirm(false);
//            }
//        }
        if (Objects.nonNull(req.getBeginDate()) && Objects.nonNull(req.getEndDate())) {
            qo.setBeginDateStr(DateUtils.formatDate(req.getBeginDate()));
            qo.setEndDateStr(DateUtils.formatDate(req.getEndDate()));
        }
        Page<Object> page = PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        List<ApprovalAndCustomerSnapshot> approvalAndCustomerSnapshotList = approvalCompletedMapper.selectByExample(qo);
        approvalAndCustomerSnapshotList.forEach(approvalAndCustomerSnapshot -> {
            approvalAndCustomerSnapshot.setNewCreditLimit(approvalAndCustomerSnapshot.getCreditLimit());
            approvalAndCustomerSnapshot.setCreditLimit(customerMapper.selectByPrimaryKey(approvalAndCustomerSnapshot.getCustomerId()).getCreditLimit());
            approvalAndCustomerSnapshot.setAddressDetails(approvalAndCustomerSnapshot.getRegionProvinceName()
                    + approvalAndCustomerSnapshot.getRegionCity()
                    + approvalAndCustomerSnapshot.getRegionArea()
                    + approvalAndCustomerSnapshot.getAddressDetails());

            approvalAndCustomerSnapshot.setChangeContent(ApprovalTypeEnum.getName(approvalAndCustomerSnapshot.getApprovalType()));
        });
        PageWrap pageWrap = new PageWrap<>();
        pageWrap.setValue(page);
        pageWrap.setResult(approvalAndCustomerSnapshotList);

        return pageWrap;
    }

    /**
     * 获取我的申请列表
     *
     * @param req
     * @return
     */
    public PageWrap getMyStartList(User user, TodoListReq req, List<String> approvalTypeCodes) {
        ApprovalListQo qo = BeanUtils.convert(ApprovalListQo.class, req);
        qo.setUserId(user.getUserId());
        qo.setApprovalTypeCodes(approvalTypeCodes);
        if (Objects.nonNull(req.getBeginDate()) && Objects.nonNull(req.getEndDate())) {
            qo.setBeginDateStr(DateUtils.formatDate(req.getBeginDate()));
            qo.setEndDateStr(DateUtils.formatDate(req.getEndDate()));
        }
        Page<Object> page = PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        List<ApprovalAndCustomerSnapshot> approvalAndCustomerSnapshotList = approvalMapper.selectByExample(qo);
        approvalAndCustomerSnapshotList.forEach(approvalAndCustomerSnapshot -> {
            approvalAndCustomerSnapshot.setNewCreditLimit(approvalAndCustomerSnapshot.getCreditLimit());
            approvalAndCustomerSnapshot.setCreditLimit(customerMapper.selectByPrimaryKey(approvalAndCustomerSnapshot.getCustomerId()).getCreditLimit());
            approvalAndCustomerSnapshot.setAddressDetails(approvalAndCustomerSnapshot.getRegionProvinceName()
                    + approvalAndCustomerSnapshot.getRegionCity()
                    + approvalAndCustomerSnapshot.getRegionArea()
                    + approvalAndCustomerSnapshot.getAddressDetails());
            approvalAndCustomerSnapshot.setChangeContent(ApprovalTypeEnum.getName(approvalAndCustomerSnapshot.getApprovalType()));
        });
        PageWrap pageWrap = new PageWrap<>();
        pageWrap.setValue(page);
        pageWrap.setResult(approvalAndCustomerSnapshotList);
        return pageWrap;
    }

    /**
     * 获取审批单状态和所有关联审批
     * @param approvalId
     * @return
     */
    public ApprovalStatus getApprovalStatus(Long approvalId) {
        ApprovalStatus approvalStatus = new ApprovalStatus();
        approvalStatus.setApprovalId(approvalId);
        approvalStatus.setApproval(approvalMapper.selectByPrimaryKey(approvalId));
        approvalStatus.setApprovalCompletedList(approvalCompletedMapper.selectByApprovalId(approvalId));
        return approvalStatus;
    }

    /**
     * 审批详情
     *
     * @param approvalId
     * @return
     */
    public SnapshotCompareResp approvalDetails(Long approvalId) {

        Approval approval = approvalMapper.selectByPrimaryKey(approvalId);
        if (Objects.isNull(approval)) {
            throw new BusinessException("审批单不存在");
        }

        CustomerSnapshot beforCustomerSnapshot = customerSnapshotMapper.selectByPrimaryKey(approval.getBeforeSnapshotId());
        CustomerSnapshot afterCustomerSnapshot = customerSnapshotMapper.selectByPrimaryKey(approval.getAfterSnapshotId());
        CustomerSnapshotResp oldData = BeanUtils.convert(CustomerSnapshotResp.class, beforCustomerSnapshot);
        CustomerSnapshotResp newData = BeanUtils.convert(CustomerSnapshotResp.class, afterCustomerSnapshot);
        oldData.setId(approval.getCustomerId());
        newData.setId(approval.getCustomerId());

        this.initUploadFileResp(oldData, beforCustomerSnapshot);
        this.initUploadFileResp(newData, afterCustomerSnapshot);

        SnapshotCompareResp snapshotCompareResp = new SnapshotCompareResp(approvalId, approval.getStatus(), oldData, newData);

        //查询 old 客户分类
        String customerType = customerService.getOldCustomerType(beforCustomerSnapshot.getCustomerCategoryId());
        oldData.setType(customerType);
//        List<UploadFile> contractFileList= new ArrayList<>();
//        List<UploadFile> thirdPartyCreditFileList= new ArrayList<>();
//        List<UploadFilePO> uploadFilePOList = JSON.parseArray(beforCustomerSnapshot.getFilePath(), UploadFilePO.class);
//        uploadFilePOList.forEach(uploadFilePO -> {
//            if (uploadFilePO.getType() == null) {
//                contractFileList.add(uploadFilePO);
//            }
//            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.CONTRACT.toString())) {
//                contractFileList.add(uploadFilePO);
//            }
//            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.THIRD_PARTY_CREDIT.toString())) {
//                thirdPartyCreditFileList.add(uploadFilePO);
//            }
//        });
//        newData.setContractFileList(contractFileList);
//        newData.setThirdPartyCreditFileList(thirdPartyCreditFileList);

        //查询 new 客户分类
        String customerNewType = customerService.getOldCustomerType(afterCustomerSnapshot.getCustomerCategoryId());
        newData.setType(customerNewType);
//        newData.setUploadFileList(JSON.parseArray(afterCustomerSnapshot.getFilePath(), UploadFile.class));
//        List<UploadFile> contractFileList= new ArrayList<>();
//        List<UploadFile> thirdPartyCreditFileList= new ArrayList<>();
//        List<UploadFilePO> uploadFilePOList = JSON.parseArray(afterCustomerSnapshot.getFilePath(), UploadFilePO.class);
//        uploadFilePOList.forEach(uploadFilePO -> {
//            if (uploadFilePO.getType() == null) {
//                contractFileList.add(uploadFilePO);
//            }
//            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.CONTRACT.toString())) {
//                contractFileList.add(uploadFilePO);
//            }
//            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.THIRD_PARTY_CREDIT.toString())) {
//                thirdPartyCreditFileList.add(uploadFilePO);
//            }
//        });
//        newData.setContractFileList(contractFileList);
//        newData.setThirdPartyCreditFileList(thirdPartyCreditFileList);


        return snapshotCompareResp;
    }

    /**
     * 初始化响应对象附件信息
     * @param resp
     * @param customerSnapshot
     */
    private void initUploadFileResp(CustomerSnapshotResp resp,  CustomerSnapshot customerSnapshot) {
        List<UploadFile> contractFileList= new ArrayList<>();
        List<UploadFile> thirdPartyCreditFileList= new ArrayList<>();
        List<UploadFilePO> uploadFilePOList = JSON.parseArray(customerSnapshot.getFilePath(), UploadFilePO.class);
        uploadFilePOList.forEach(uploadFilePO -> {
            if (uploadFilePO.getType() == null) {
                contractFileList.add(uploadFilePO);
            }
            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.CONTRACT.toString())) {
                contractFileList.add(uploadFilePO);
            }
            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.THIRD_PARTY_CREDIT.toString())) {
                thirdPartyCreditFileList.add(uploadFilePO);
            }
        });
        resp.setContractFileList(contractFileList);
        resp.setThirdPartyCreditFileList(thirdPartyCreditFileList);
    }


    /**
     * 通过/拒绝
     *
     * @param
     * @param confirm
     * @param rejectReason
     */
    @Transactional(rollbackFor = Exception.class)
    public void confirm(User user, Long approvalId, Boolean confirm, String rejectReason) {
        /*单据校验*/
        Approval approval = approvalMapper.selectByPrimaryKey(approvalId);
        if (Objects.isNull(approval)) {
            throw new BusinessException("审批单不存在");
        }
        List<ApprovalTodo> approvalTodoList = approvalTodoMapper.selectByApprovalUserIdAndApprovalId(user.getUserId(), approvalId);
        if (Objects.isNull(approvalTodoList) || approvalTodoList.size() == 0) {
            throw new BusinessException("待处理审批单不存在或已审批");
        }
        /*确认同一个节点的其他人是否审批过*/
        ApprovalCompleted approvalCompleted = approvalCompletedMapper.selectByApprovalIdAndNode(approval.getId(), approval.getCurrentNodeCode());
        if (Objects.nonNull(approvalCompleted)) {
            throw new BusinessException("该申请已由" + approvalCompleted.getApprovalUserName() + "审批，无需重复操作");
        }

        /*落地节点审批完成记录*/
        approvalCompleted = new ApprovalCompleted();
        approvalCompleted.setApprovalId(approvalId);
        approvalCompleted.setApprovalUserId(user.getUserId());
        approvalCompleted.setApprovalUserName(user.getUserName());
        approvalCompleted.setNodeCode(approval.getCurrentNodeCode());
        approvalCompleted.setConfirm(confirm);
        approvalCompleted.setRejectReason(rejectReason);
        approvalCompleted.setCreateTime(new Date());
        approvalCompletedMapper.insertSelective(approvalCompleted);

        /*删除当前节点待办记录*/
        approvalTodoMapper.deleteByApprovalId(approvalId);

        /*判断流程是否结束*/
        List<FlowNodeJSON> flowNodeJSONList = JSON.parseArray(approval.getFlowNode(), FlowNodeJSON.class);
        for (int i = 0; i < flowNodeJSONList.size() - 1; i++) {
            if (flowNodeJSONList.get(i).getNode().getCode().equals(approval.getCurrentNodeCode())) {
                String nextNodeCode = flowNodeJSONList.get(i + 1).getNode().getCode();
                /*流程节点通过*/
                if (confirm && !nextNodeCode.equals(ApprovalFlowEnum.COMPLETE.getCode())) {
                    /*流程继续*/
                    approval.setCurrentNodeCode(nextNodeCode);
                    approvalMapper.updateByPrimaryKeySelective(approval);
                    /*生成待办*/
                    List<FlowNodeJSON.Person> personList = flowNodeJSONList.get(i + 1).getPerson();
                    personList.forEach(person -> {
                        ApprovalTodo approvalTodo = new ApprovalTodo();
                        approvalTodo.setApprovalId(approval.getId());
                        approvalTodo.setApprovalUserId(Long.valueOf(person.getCode()));
                        approvalTodoMapper.insertSelective(approvalTodo);
                        this.sendTodoMessage(approvalTodo.getApprovalUserId(), approval.getApprovalNumber().toString(), ApprovalTypeEnum.getName(approval.getApprovalType()));
                    });
                }
                /*流程节点拒绝*/
                if (!confirm) {
                    Customer customer = customerMapper.selectByPrimaryKey(approval.getCustomerId());
                    if (Objects.isNull(customer)) {
                        throw new BusinessException("审批流程完成时客户不存在");
                    }
                    if (approval.getApprovalType().equals(ApprovalTypeEnum.NEW.getCode())){
                        customer.setCustomerStatus(CustomerStatusEnum.REJECT.getCode());
                        customerMapper.updateByPrimaryKeySelective(customer);
                    }


                    approval.setStatus(ApprovalStatusEnum.REJECT.getCode());
                    approvalMapper.updateByPrimaryKeySelective(approval);

                    this.sendCompletedMessage(approval.getStartUserId(), approval.getApprovalNumber().toString(),
                            ApprovalTypeEnum.getName(approval.getApprovalType()), ApprovalStatusEnum.REJECT.getName());

                    break;
                }
                /*流程审批完成*/
                if (nextNodeCode.equals(ApprovalFlowEnum.COMPLETE.getCode())) {
                    Customer oldCustomer = customerMapper.selectByPrimaryKey(approval.getCustomerId());
                    CustomerSnapshot afterCustomerSnapshot = customerSnapshotMapper.selectByPrimaryKey(approval.getAfterSnapshotId());
                    if (Objects.isNull(oldCustomer)) {
                        throw new BusinessException("审批流程完成时客户不存在");
                    }
                    if (Objects.isNull(afterCustomerSnapshot)) {
                        throw new BusinessException("审批流程完成时客户快照不存在");
                    }
                    Customer newCustomer = BeanUtils.convert(Customer.class, afterCustomerSnapshot);
                    newCustomer.setId(oldCustomer.getId());
                    /*修改审批单状态*/
                    approval.setStatus(ApprovalStatusEnum.PASS.getCode());
                    approvalMapper.updateByPrimaryKeySelective(approval);
                    if (ApprovalTypeEnum.NEW.getCode().equals(approval.getApprovalType())) {
                        /*修改客户状态*/
                        newCustomer.setCustomerStatus(CustomerStatusEnum.PASS.getCode());
                        if (log.isDebugEnabled()) {
                            log.debug(ApprovalTypeEnum.NEW.getName() + newCustomer.toString());
                        }
                        customerMapper.updateByPrimaryKeySelective(newCustomer);

                        sapLogic.create(newCustomer);
                    } else if (ApprovalTypeEnum.MODIFY.getCode().equals(approval.getApprovalType())) {
                        /*地址解析*/
                        if (StringUtils.isNotBlank(newCustomer.getRegionProvinceName()) && StringUtils.isNotBlank(newCustomer.getRegionCity()) && StringUtils.isNotBlank(newCustomer.getRegionArea())) {
                            double[] resolveAddress = null;
                            try {
                                resolveAddress = geoService.resolveAddress(newCustomer.getRegionProvinceName() +
                                        newCustomer.getRegionCity() + newCustomer.getRegionArea() + newCustomer.getAddressDetails());
                            } catch (Exception e) {
                                log.error(e.getMessage(), e);
                            }
                            if (resolveAddress != null) {
                                newCustomer.setLongitude(BigDecimal.valueOf(resolveAddress[0]));
                                newCustomer.setLatitude(BigDecimal.valueOf(resolveAddress[1]));
                            }
                        }
                        if (log.isDebugEnabled()) {
                            log.debug(ApprovalTypeEnum.MODIFY.getName() + newCustomer.toString());
                        }
                        customerMapper.updateByPrimaryKeySelective(newCustomer);
                        sapLogic.edit(newCustomer, 1);
                    } else if (ApprovalTypeEnum.CREDIT.getCode().equals(approval.getApprovalType())) {
                        CustomerCompanyExt customerCompanyExt = customerCompanyExtMapper.selectCompanyCodeInfo(newCustomer.getId(), newCustomer.getCompanyCode());
                        if (customerCompanyExt != null) {
                            customerCompanyExt.setCreditLimit(newCustomer.getCreditLimit());
                            customerCompanyExt.setCustomerLevel(newCustomer.getCustomerLevel());
                            customerCompanyExt.setPaymentDays(newCustomer.getPaymentDays());
                            customerCompanyExt.setPaymentTerms(newCustomer.getPaymentTerms());
                            customerCompanyExt.setSaleOrganization(newCustomer.getSaleOrganization());
                            if (log.isDebugEnabled()) {
                                log.debug("扩公司" + ApprovalTypeEnum.CREDIT.getName() + customerCompanyExt.toString());
                            }
                            customerCompanyExtMapper.updateByPrimaryKeySelective(customerCompanyExt);
                        } else {
                            if (log.isDebugEnabled()) {
                                log.debug(ApprovalTypeEnum.CREDIT.getName() + newCustomer.toString());
                            }
                            customerMapper.updateByPrimaryKeySelective(newCustomer);
                        }
                        sapLogic.edit(newCustomer, 1);
                    } else if (ApprovalTypeEnum.EXT_COMPANY.getCode().equals(approval.getApprovalType())) {
                        // 追加公司扩展信息
                        this.expansionInfo(user, newCustomer);
                        sapLogic.edit(newCustomer, 2);
                    } else if (ApprovalTypeEnum.TEMP_CREDIT.getCode().equals(approval.getApprovalType())) {
                        customerMapper.updateByPrimaryKeySelective(newCustomer);
                        sapLogic.edit(newCustomer, 1);
                    }

                    this.sendCompletedMessage(approval.getStartUserId(), approval.getApprovalNumber().toString(),
                            ApprovalTypeEnum.getName(approval.getApprovalType()), ApprovalStatusEnum.PASS.getName());
                }
                break;
            }
        }
    }

    public AppGetExpandInfoResp getAllCompanyCode(String companyName) {
        List<String> list = sysCompanyCodeMapper.selectgetCompanyCode(companyName);
        List<AppGetExpandInfoResp> apps = BeanUtils.convertList(AppGetExpandInfoResp.class, list);
        AppGetExpandInfoResp AppGetExpandInfoResp= new AppGetExpandInfoResp();
        AppGetExpandInfoResp.setList(apps);
        return AppGetExpandInfoResp;
    }

    public boolean expansionInfo(User user, Customer customer) {
        String companyCode = customer.getCompanyCode();
        Long customerId = customer.getId();
        //根据  客户id  和  公司代码 查询
        List<CustomerCompanyExt> list = customerCompanyExtMapper.selectExistQuery(customerId, companyCode);
        if (null == list || list.size() == 0) {
            //没有记录 需要记录
            CustomerCompanyExt customerCompanyExt = new CustomerCompanyExt();
            customerCompanyExt.setCustomerId(customer.getId());
            customerCompanyExt.setCompanyCode(customer.getCompanyCode());
            customerCompanyExt.setSaleOrganization(customer.getSaleOrganization());
            customerCompanyExt.setPaymentTerms(customer.getPaymentTerms());
            customerCompanyExt.setCreditLimit(customer.getCreditLimit());
            customerCompanyExt.setPaymentDays(customer.getPaymentDays());
            customerCompanyExt.setCustomerLevel(customer.getCustomerLevel());
            customerCompanyExt.setCreateTime(new Date());
            customerCompanyExt.setCreateBy(user.getUserName() == null ? "" : user.getUserName());
            customerCompanyExt.setUpdateBy("sys");
            customerCompanyExt.setUpdateTime(new Date());
            customerCompanyExtMapper.insert(customerCompanyExt);
        } else if (list.size() == 1) {
            //有记录 不需要操作
        } else if (list.size() > 1) {
            //多条记录 异常 暂不进行操作
        }
        return true;
    }

    public CustomerAddBigResp getDraftInfo(Long userId){
       Customer customer =  customerMapper.selectByPrimaryKey(userId);
        CustomerAddBigResp customerAddReq = BeanUtils.convert(CustomerAddBigResp.class,customer);
//        customerAddReq.setUploadFileList(JSON.parseArray(customer.getFilePath(), UploadFile.class));
        List<UploadFile> contractFileList= new ArrayList<>();
        List<UploadFile> thirdPartyCreditFileList= new ArrayList<>();
        List<UploadFilePO> uploadFilePOList = JSON.parseArray(customer.getFilePath(), UploadFilePO.class);
        uploadFilePOList.forEach(uploadFilePO -> {
            if (uploadFilePO.getType() == null) {
                contractFileList.add(uploadFilePO);
            }
            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.CONTRACT.toString())) {
                contractFileList.add(uploadFilePO);
            }
            else if (uploadFilePO.getType().equals(UploadFileTypeEnum.THIRD_PARTY_CREDIT.toString())) {
                thirdPartyCreditFileList.add(uploadFilePO);
            }
        });
        customerAddReq.setContractFileList(contractFileList);
        customerAddReq.setThirdPartyCreditFileList(thirdPartyCreditFileList);
        return customerAddReq;
    }

}
